
#include <iostream.h>
#include "classGFG.h"
#include "MacrosPorts.h"




/****************************************************************************************************/
/*                  S U P E R     H I G H     P U B L I C      F U N C T I O N S                    */
/****************************************************************************************************/
bool GFG::GetCurrentParameters(GFGdata *pCurrData)
{

//  wrChar(1); wrChar(2); wrChar(3); wrChar(1); wrChar(7);wrChar(0); wrChar(0x2b); wrChar(0xa5); 

//    wrChar(1); wrChar(2); wrChar(3); wrChar(1); wrChar(180);wrChar(4);  wrChar(1);
//    wrChar(46); wrChar(0); wrChar(53);     wrChar(0x53); wrChar(0xE6); 
//    wrChar(57); wrChar(0); wrChar(1);     wrChar(0xE2); wrChar(0x35); 
//    wrChar(57); wrChar(0); wrChar(2);     wrChar(0xA2); wrChar(0x34); 
    
//    wrChar(1); wrChar(2); wrChar(3); wrChar(1); wrChar(181);wrChar(6);  wrChar(1);
//    wrChar(57); wrChar(0); wrChar(4);     wrChar(0xe8); wrChar(0x03); 
//    wrChar(0x74); wrChar(0xbb); 
  

//    wrChar(1); wrChar(2); wrChar(3); wrChar(1); wrChar(17);wrChar(5);
//    wrChar('L'); wrChar('O'); wrChar('I');     wrChar(0xe8); wrChar(0x03); 
//    wrChar(0xA9); wrChar(0x93); 

    wrChar(1); wrChar(2); wrChar(3); wrChar(1); wrChar(180);wrChar(4);
    wrChar(1); wrChar(15); wrChar(0); wrChar(11);
    wrChar(0x82); wrChar(0x3c); 
 
  
  
  //  FormCOM40();
  if(askGFG(40))
    {
      InStrt = (*pUx).shift(InStrt,7);
      (*pCurrData).Time.year = BCDtoCHAR( (*pUx).RdBufIn(InStrt) );  (*pUx).next(&InStrt);
      (*pCurrData).Time.mnth = BCDtoCHAR( (*pUx).RdBufIn(InStrt) );  (*pUx).next(&InStrt);
      (*pCurrData).Time.date = BCDtoCHAR( (*pUx).RdBufIn(InStrt) );  (*pUx).next(&InStrt);
      (*pCurrData).Time.hour = BCDtoCHAR( (*pUx).RdBufIn(InStrt) );  (*pUx).next(&InStrt);
      (*pCurrData).Time.min  = BCDtoCHAR( (*pUx).RdBufIn(InStrt) );  (*pUx).next(&InStrt);
      (*pCurrData).Time.sec  = BCDtoCHAR( (*pUx).RdBufIn(InStrt) );  (*pUx).next(&InStrt);
      if(NofByte==38)
        { 
          (*pCurrData).Err = 0;
          (*pCurrData).Q = BUFtoFLOAT();
          (*pCurrData).T = BUFtoFLOAT();
          (*pCurrData).P = BUFtoFLOAT();
          (*pCurrData).Qsum = BUFtoFLOAT();
         }
       else
        { 
          (*pCurrData).Err = (*pUx).RdBufIn(InStrt);
          (*pCurrData).Q = (*pCurrData).T = (*pCurrData).P = (*pCurrData).Qsum = 0;
        }
      return true;
     }
  return false;
}





bool GFG::GetArMP(DataTime *pRecordTime, GFGarch *pArD)
{ uint hr; usht error;
//  
  FormCOM41_2(42,(*pRecordTime).year,(*pRecordTime).mnth,(*pRecordTime).date);
  if(askGFG(42))
    {
      InStrt = (*pUx).shift(InStrt,3);
      D.yy = BCDtoCHAR( (*pUx).RdBufIn(InStrt) );  (*pUx).next(&InStrt);
      D.mm = BCDtoCHAR( (*pUx).RdBufIn(InStrt) );  (*pUx).next(&InStrt);
      D.dd = BCDtoCHAR( (*pUx).RdBufIn(InStrt) );
      InStrt = (*pUx).shift(InStrt,7);
      if(NofByte==254)
        { 
          D.hh = BCDtoCHAR( (*pUx).RdBufIn(InStrt) ); (*pUx).next(&InStrt);
          for(hr=0; hr<24; ++hr)
           {
             (*pArD).Q = BUFtoFLOAT();
             (*pArD).T = BUFtoTEMP();
             (*pArD).P = BUFtoPRES();
             (*pArD).Err = BUFtoERR();
             (*pArD).AD = D; NextHour();
             ++pArD;
            }
         }
       else
        { 
          error = (*pUx).RdBufIn(InStrt);   D.hh = 24;
          for(hr=0; hr<24; ++hr)
           {
             (*pArD).Q = (*pArD).T = (*pArD).P = 0;
             (*pArD).Err = error;   (*pArD).AD = D;
             ++pArD;
            }
         }
      return true;
     }
  return false;
}


bool GFG::GetArDay(DataTime *pRecordTime, GFGarch *pArD)
{
  FormCOM41_2(41,(*pRecordTime).year,(*pRecordTime).mnth,(*pRecordTime).date);
  if(askGFG(41))
    {
      InStrt = (*pUx).shift(InStrt,3);
      (*pArD).AD.yy = BCDtoCHAR( (*pUx).RdBufIn(InStrt) );  (*pUx).next(&InStrt);
      (*pArD).AD.mm = BCDtoCHAR( (*pUx).RdBufIn(InStrt) );  (*pUx).next(&InStrt);
      (*pArD).AD.dd = BCDtoCHAR( (*pUx).RdBufIn(InStrt) );
      InStrt = (*pUx).shift(InStrt,7);
      if(NofByte==32)
        { 
          (*pArD).AD.hh = BCDtoCHAR( (*pUx).RdBufIn(InStrt) );
          InStrt = (*pUx).shift(InStrt,5);
          (*pArD).T = BUFtoFLOAT();
          (*pArD).P = BUFtoFLOAT();
          (*pArD).Q = BUFtoFLOAT();
          (*pArD).Err = BUFtoMIN();
         }
       else
        { 
          (*pArD).Err = (*pUx).RdBufIn(InStrt);
          (*pArD).AD.hh = 24;
          (*pArD).Q = (*pArD).T = (*pArD).P =  0;
        }
      return true;
     }
  return false;
}




float GFG::PutAnyoneParameter(uint Adr, float Param)
{
//open castle  
  if(!startEK()) return 0;               if(!OpenSLcastle()) return 0;
//write & check parameter
  if(!putPARAMfl(Adr,Param)) return 0;   if(!getPARAMfl(Adr,&Param)) return 0;
//close castle
  CloseSLcastle();
//
  return Param;
}



/****************************************************************************************************/
/*                             P U B L I C      F U N C T I O N S                                   */
/****************************************************************************************************/

GFG::GFG(UARTbuf *pUART) {pUx = pUART; vrgID = 255; ChNumb = 1;}
/****************************************************************************************************/

GFG::GFG(UARTbuf *pUART, char VRGid) {pUx = pUART; vrgID = VRGid; ChNumb = 1;}
/****************************************************************************************************/


/****************************************************************************************************/



/****************************************************************************************************/
/*                            P R I V A T E      F U N C T I O N S                                  */
/****************************************************************************************************/


bool GFG::askGFG(char Com)
{ (*pUx).SetBrdOISR(); /*U3_485_DE;*/ (*pUx).StartTransmite(); return CheckAnswer(Com); }
/****************************************************************************************************/
/****************************************************************************************************/



void GFG::FormCOM40(void)
{ CheckSum = 0; wrChar(40); wrChar(vrgID); wrChar(ChNumb); wrCheckSum(); }
/****************************************************************************************************/

void GFG::FormCOM41_2(char com, char yy, char mm, char dd)
{
  CheckSum = 0;
  wrChar(com); wrChar(vrgID); wrChar(ChNumb);  wrBCD(yy); wrBCD(mm); wrBCD(dd);   wrCheckSum();
}
/****************************************************************************************************/



/****************************************************************************************************/

usht GFG::BUFtoMIN(void)
{ usht val;
//  
  val = BCDtoCHAR((*pUx).RdBufIn(InStrt))*60;  (*pUx).next(&InStrt);
  val += BCDtoCHAR((*pUx).RdBufIn(InStrt));
//
  return val;
}

float GFG::BUFtoTEMP(void)
{ uint bcd;
//
  bcd = ( (uint)((*pUx).RdBufIn(InStrt)) )<<8;   (*pUx).next(&InStrt);
  bcd += (*pUx).RdBufIn(InStrt);  (*pUx).next(&InStrt);
//
  if(bcd&0x8000)
    { return ((float)BCDtoUINT(bcd&0x7FFF))/(-100); }
   else
    { return ((float)BCDtoUINT(bcd))/100; }
}


float GFG::BUFtoPRES(void)
{ uint bcd;
//
  bcd = ( (uint)((*pUx).RdBufIn(InStrt)) )<<12;  (*pUx).next(&InStrt);
  bcd += ( (uint)((*pUx).RdBufIn(InStrt)) )<<4;  (*pUx).next(&InStrt);
  bcd += (*pUx).RdBufIn(InStrt)>>4;
//
  return ((float)BCDtoUINT(bcd))/1000;
}


usht GFG::BUFtoERR(void)
{ usht err;
  err = ( (usht)((*pUx).RdBufIn(InStrt)) )<<12;  (*pUx).next(&InStrt);
  err += BCDtoCHAR((*pUx).RdBufIn(InStrt));  (*pUx).next(&InStrt);
  return err;
}

uint GFG::BCDtoUINT(uint bcd)
{ uint val=0, mul=1;
  while(bcd) {val+=(bcd&0xF)*mul; bcd>>=4; mul*=10;}
  return val;
};


float GFG::BUFtoFLOAT(void)
{ float val;   char *p;
//  
  p = ((char *)&val)+3;
  *p-- = (*pUx).RdBufIn(InStrt);  (*pUx).next(&InStrt);
  *p-- = (*pUx).RdBufIn(InStrt);  (*pUx).next(&InStrt);
  *p-- = (*pUx).RdBufIn(InStrt);  (*pUx).next(&InStrt);
  *p   = (*pUx).RdBufIn(InStrt);  (*pUx).next(&InStrt);
//
  return val;
}



void GFG::NextHour(void)
{ 
  if(++D.hh>23)
   {
     D.hh = 0;
     switch(++D.dd)
      {
        case(29): if(D.mm==2 && D.yy%4) {D.mm=3; D.dd=1;}; break; 
        case(30): if(D.mm==2 && !(D.yy%4)) {D.mm=3; D.dd=1;}; break; 
        case(31): if(D.mm!=4 && D.mm!=6 && D.mm!=9 && D.mm!=11) break; 
        case(32): ++D.mm; D.dd=1; break; 
       }
     if(D.mm>12) {D.mm=1; ++D.yy;}
    }
}
/****************************************************************************************************/


/****************************************************************************************************/




bool GFG::CheckAnswer(char Com)
{ 
  static uint InInd=0;
  uint InEnd; char checkSum=0, ch1; 
//all answer recieve waiting
  if( !(*pUx).RecieveIndI(&InEnd,1300) ) return false;
  while( (*pUx).RecieveIndI(&InEnd,100) );
//command checking
  while( (*pUx).RdBufIn(InInd)!=Com )
    { (*pUx).next(&InInd); if(InInd==InEnd) return false; }
  InStrt = InInd;   NofByte = (*pUx).CountBytes(InStrt,InEnd);
  switch(Com)
   {
     case(40): if(NofByte<38)  {NofByte=15;} else {NofByte=38;}; break;
     case(41): if(NofByte<32)  {NofByte=14;} else {NofByte=32;}; break;
     case(42): if(NofByte<254) {NofByte=14;} else {NofByte=254;}; break;
    }
//CheckSum Calculation
  for(ch1=0; ch1<NofByte; ++ch1)
    {checkSum += (*pUx).RdBufIn(InInd); (*pUx).next(&InInd);}
  if(!checkSum) {return true;} else {return false;} 
//
}
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/